<template>
  <!-- 加载gltf模型 -->
  <div id="scene" @click="onClickModel"></div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

let scene; //场景
let camera; //相机
let renderer; //创建渲染器
let controls; //控制器

let raycaster;
let mouse;
export default {
  name: "Scene",
  data() {
    return {};
  },
  computed: {
    windowWidth() {
      return window.innerWidth - 200;
    },
  },
  mounted() {
    this.init();
    this.createControls();
    this.addGLTF();
    this.render();
  },
  methods: {
    onClickModel(e) {
      // 通过鼠标点击位置,计算出 raycaster 所需点的位置,以屏幕为中心点,范围 -1 到 1
      mouse.x = ((e.clientX - 200) / this.windowWidth) * 2 - 1; //左侧导航菜单width占了200px,计算时去除
      mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;

      //通过鼠标点击的位置和当前相机的矩阵计算出射线位置
      raycaster.setFromCamera(mouse, camera);

      // 获取与射线相交的对象数组，按照距离排序，越近的越靠前
      const intersects = raycaster.intersectObjects(this.group.children);

      console.log(intersects);
    },
    init() {
      //创建场景
      scene = new THREE.Scene();
      // 声明 raycaster 和 mouse 变量
      raycaster = new THREE.Raycaster();
      mouse = new THREE.Vector2();

      const container = document.getElementById("scene");
      const width = container.clientWidth;
      const height = container.clientHeight;
      /**
       * 透视投影相机设置
       */
      camera = new THREE.PerspectiveCamera(60, width / height, 1, 100000);
      camera.position.set(600, 900, 600); // 树上面观察
      camera.lookAt(scene.position); // 设置相机方向(指向的场景对象)
      // 创建渲染器对象
      renderer = new THREE.WebGLRenderer({ alpha: true });
      renderer.setSize(width, height); // 设置渲染区域尺寸
      container.appendChild(renderer.domElement); // body元素中插入canvas对象
      //创建点光源和环境光源
      const point = new THREE.PointLight(0xffffff);
      point.position.set(600, 900, 600); // 点光源位置
      scene.add(point); // 点光源添加到场景中
      // 环境光
      const ambient = new THREE.AmbientLight(0x888888);
      scene.add(ambient);
    },
    createControls() {
      controls = new OrbitControls(camera, renderer.domElement);
    },
    render() {
      renderer.render(scene, camera);
      requestAnimationFrame(this.render); // 请求再次执行渲染函数render
    },
    addGLTF() {
      const loader = new GLTFLoader();
      loader.load("/model/shanghai.gltf", (gltf) => {
        scene.add(gltf.scene);
      });
    },
  },
};
</script>

<style scoped lang="less">
#scene {
  width: 100%;
  height: 100%;
}
</style>
